﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Mail;
using System.Net;
using System.Runtime.Remoting.Messaging;

namespace ChatForum.Messaging
{
    public class SmtpServerBase
    {
        private SmtpClient sender;
        private string defaultFromAddress;
        public SmtpServerBase(string host, int port, string userName, string password)
        {
            if (string.IsNullOrWhiteSpace(host))
                throw new ArgumentNullException("host");
            if (string.IsNullOrWhiteSpace(userName))
                throw new ArgumentNullException("userName");
            if (string.IsNullOrWhiteSpace(password))
                throw new ArgumentNullException("password");

            sender = new SmtpClient(host, port);
            sender.UseDefaultCredentials = false;
            sender.Credentials = new NetworkCredential(userName, password);
            sender.Timeout = 10000;
            sender.DeliveryMethod = SmtpDeliveryMethod.Network;
            //as the following error coming
            //The SMTP server requires a secure connection or the client was not authenticated.
            //The server response was: 5.7.0 Must issue a STARTTLS command first.
            //ag4sm3386251pbc.20 - gsmtp
            sender.EnableSsl = true;

            defaultFromAddress = userName;
        }

        private delegate void SendAsynchMassageCaller(string fromAddress, IEnumerable<string> toAddresses, string messageBody, string subject, IEnumerable<string> ccAddresses, IEnumerable<string> bccAddresses);

        public void SendMessage(string fromAddress, IEnumerable<string> toAddresses, string messageBody, string subject, IEnumerable<string> ccAddresses, IEnumerable<string> bccAddresses)
        {
            if (toAddresses == null || toAddresses.Count() == 0)
                throw new ArgumentNullException("toAddresses");
            if (string.IsNullOrWhiteSpace(messageBody))
                throw new ArgumentNullException("messageBody");

            MailMessage message = new MailMessage();

            if (string.IsNullOrWhiteSpace(fromAddress))
                fromAddress = defaultFromAddress;
            message.From = new MailAddress(fromAddress);

            foreach (string toAddress in toAddresses)
                message.To.Add(new MailAddress(toAddress));

            if (ccAddresses != null && ccAddresses.Count() > 0)
                foreach (string ccAddress in ccAddresses)
                    if (!string.IsNullOrWhiteSpace(ccAddress))
                        message.CC.Add(new MailAddress(ccAddress));

            if (bccAddresses != null && bccAddresses.Count() > 0)
                foreach (string bccAddress in bccAddresses)
                    if (!string.IsNullOrWhiteSpace(bccAddress))
                        message.Bcc.Add(new MailAddress(bccAddress));

            message.Subject = subject;
            message.Body = messageBody;

            sender.Send(message);
        }
        public void SendMessage(MailAddress fromAddress, MailAddressCollection toAddresses, string messageBody, string subject, MailAddressCollection ccAddresses, MailAddressCollection bccAddresses)
        {
            if (toAddresses == null || toAddresses.Count == 0)
                throw new ArgumentNullException("toAddresses");
            if (string.IsNullOrWhiteSpace(messageBody))
                throw new ArgumentNullException("messageBody");

            MailMessage message = new MailMessage();

            if (fromAddress == null)
                fromAddress = new MailAddress(defaultFromAddress);
            message.From = fromAddress;

            foreach (MailAddress toAddress in toAddresses)
                message.To.Add(toAddress);

            if (ccAddresses != null && ccAddresses.Count() > 0)
                foreach (MailAddress ccAddress in ccAddresses)
                    message.CC.Add(ccAddress);

            if (bccAddresses != null && bccAddresses.Count() > 0)
                foreach (MailAddress bccAddress in bccAddresses)
                    message.Bcc.Add(bccAddress);

            message.Subject = subject;
            message.Body = messageBody;

            sender.Send(message);
        }
        public void SendMessage(MailMessage message)
        {
            if (message == null)
                throw new ArgumentNullException("message");

            sender.Send(message);
        }

        public void SendAsynchMessage(string fromAddress, IEnumerable<string> toAddresses, string messageBody, string subject, IEnumerable<string> ccAddresses, IEnumerable<string> bccAddresses)
        {
            SendAsynchMassageCaller caller = new SendAsynchMassageCaller(SendMessage);
            caller.BeginInvoke(fromAddress, toAddresses, messageBody, subject, ccAddresses, bccAddresses, new AsyncCallback(SendAsynchMessageCallback), null);
        }
        private void SendAsynchMessageCallback(IAsyncResult ar)
        {
            AsyncResult result = (AsyncResult)ar;
            SendAsynchMassageCaller caller = (SendAsynchMassageCaller)result.AsyncDelegate;
            caller.EndInvoke(ar);
        }
    }
}